package com.gitee.wsl.mathematics.function.noise

/*

class FreeWorleyNoise2d(nPoints: Int, seed: Int = 19937) : Noise2d {

    private val pointTree: KdTree<Vec3f>
    private val trav = NearestTraverser<Vec3f>()

    private val tmpVec = MutableVec3f()
    private val scale = nPoints.toFloat().pow(1f / 2f) / MAX_D

    init {
        val rand = Random(seed)
        val points = List(nPoints * 9) { MutableVec3f() }
        for (i in 0 until nPoints) {
            val p = Vec3f(rand.nextFloat(), rand.nextFloat(), 0f)
            var j = i * 9
            for (py in -1..1) {
                for (px in -1..1) {
                    points[j++].set(p.x + px, p.y + py, 0f)
                }
            }
        }
        pointTree = KdTree(points, Vec3fAdapter())
    }

    override fun eval(x: Float, y: Float): Float {
        trav.setup(Vec3f.ZERO)
        trav.center.set(x.toDouble(), y.toDouble(), 0.0)
        trav.traverse(pointTree)

        val n = trav.nearest
        return if (n != null) {
            n.distance(trav.center.toMutableVec3f(tmpVec)) * scale
        } else {
            1f
        }
    }

    companion object {
        private val MAX_D = sqrt(2f)
    }
}

class FreeWorleyNoise3d(nPoints: Int, seed: Int = 19937) : Noise3d {

    private val pointTree: KdTree<Vec3f>
    private val trav = NearestTraverser<Vec3f>()

    private val tmpVec = MutableVec3f()
    private val scale = nPoints.toFloat().pow(1f / 3f) / MAX_D

    init {
        val rand = Random(seed)
        val points = List(nPoints * 27) { MutableVec3f() }
        for (i in 0 until nPoints) {
            val p = Vec3f(rand.randomF(), rand.randomF(), rand.randomF())
            var j = i * 27
            for (pz in -1..1) {
                for (py in -1..1) {
                    for (px in -1..1) {
                        points[j++].set(p.x + px, p.y + py, p.z + pz)
                    }
                }
            }
        }
        pointTree = KdTree(points, Vec3fAdapter())
    }

    override fun eval(x: Float, y: Float, z: Float): Float {
        trav.setup(Vec3f.ZERO)
        trav.center.set(x.toDouble(), y.toDouble(), z.toDouble())
        trav.traverse(pointTree)

        val n = trav.nearest
        return if (n != null) {
            n.distance(trav.center.toMutableVec3f(tmpVec)) * scale
        } else {
            1f
        }
    }

    companion object {
        private val MAX_D = sqrt(3f)
    }
}*/
